/* LEDC (LED Controller) fade example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include "driver/ledc.h"
#include "driver/mcpwm_prelude.h"
#include "esp_err.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/task.h"
#include <stdio.h>

// gpio32/33/35 led1/led2/led3
#define LEDC_HS_TIMER LEDC_TIMER_0
#define LEDC_HS_MODE LEDC_LOW_SPEED_MODE
#define LEDC_HS_CH0_GPIO (32)
#define LEDC_HS_CH0_CHANNEL LEDC_CHANNEL_0
#define LEDC_HS_CH1_GPIO (33)
#define LEDC_HS_CH1_CHANNEL LEDC_CHANNEL_1
#define LEDC_HS_CH2_GPIO (22)
#define LEDC_HS_CH2_CHANNEL LEDC_CHANNEL_2
#define LEDC_HS_CH3_GPIO (17)
#define LEDC_HS_CH3_CHANNEL LEDC_CHANNEL_3

#define LED_BLUETOOTH GPIO_NUM_17 // 蓝牙连接指示灯
#define LED1_GPIO GPIO_NUM_32
#define LEDC_TEST_CH_NUM (3)
#define LEDC_FREQ (1000) // 4k频率

// Please consult the datasheet of your servo before changing the following
// parameters
#define SERVO_MIN_PULSEWIDTH_US 500  // Minimum pulse width in microsecond
#define SERVO_MAX_PULSEWIDTH_US 2500 // Maximum pulse width in microsecond
#define SERVO_MIN_DEGREE -90         // Minimum angle
#define SERVO_MAX_DEGREE 90          // Maximum angle

// GPIO connects to the PWM signal line 电机引脚
#define SERVO_PULSE_GPIO 25
#define SERVO_TIMEBASE_RESOLUTION_HZ 1000000 // 1MHz, 1us per tick
#define SERVO_TIMEBASE_PERIOD 20000          // 20000 ticks, 20ms

static const char *TAG = "ledc_mcpwm";

mcpwm_cmpr_handle_t comparator = NULL;
SemaphoreHandle_t counting_sem = NULL;
ledc_channel_config_t ledc_channel[LEDC_TEST_CH_NUM] = {
    {.channel = LEDC_HS_CH0_CHANNEL,
     .duty = 0,
     .gpio_num = LEDC_HS_CH0_GPIO,
     .speed_mode = LEDC_HS_MODE,
     .hpoint = 0,
     .timer_sel = LEDC_HS_TIMER,
     .flags.output_invert = 0},
    {.channel = LEDC_HS_CH1_CHANNEL,
     .duty = 0,
     .gpio_num = LEDC_HS_CH1_GPIO,
     .speed_mode = LEDC_HS_MODE,
     .hpoint = 0,
     .timer_sel = LEDC_HS_TIMER,
     .flags.output_invert = 0},

    {.channel = LEDC_HS_CH2_CHANNEL,
     .duty = 0,
     .gpio_num = LEDC_HS_CH2_GPIO,
     .speed_mode = LEDC_HS_MODE,
     .hpoint = 0,
     .timer_sel = LEDC_HS_TIMER,
     .flags.output_invert = 0},
    //  {.channel = LEDC_HS_CH3_CHANNEL,
    //  .duty = 0,
    //  .gpio_num = LEDC_HS_CH3_GPIO,
    //  .speed_mode = LEDC_HS_MODE,
    //  .hpoint = 0,
    //  .timer_sel = LEDC_HS_TIMER,
    //  .flags.output_invert = 0},

};

void led_init(void) {

  int ch;
  /*
   * Prepare and set configuration of timers
   * that will be used by LED Controller
   */
  ledc_timer_config_t ledc_timer = {
      .duty_resolution = LEDC_TIMER_13_BIT, // resolution of PWM duty
      .freq_hz = LEDC_FREQ,                 // frequency of PWM signal
      .speed_mode = LEDC_HS_MODE,           // timer mode
      .timer_num = LEDC_HS_TIMER,           // timer index
      .clk_cfg = LEDC_AUTO_CLK,             // Auto select the source clock
  };
  // Set configuration of timer0 for high speed channels
  ledc_timer_config(&ledc_timer);

  // Set LED Controller with previously prepared configuration
  for (ch = 0; ch < LEDC_TEST_CH_NUM; ch++) {
    ledc_channel_config(&ledc_channel[ch]);
  }
}

void led_start(void *args) {

  while (1) {

    gpio_set_level(LED_BLUETOOTH, 1);
    for (int i = 0; i < LEDC_TEST_CH_NUM; i++) {
      ledc_set_duty(ledc_channel[i].speed_mode, ledc_channel[i].channel, 1639);
      ledc_update_duty(ledc_channel[i].speed_mode, ledc_channel[i].channel);
      vTaskDelay(3000 / portTICK_PERIOD_MS);
    }

    for (int i = 0; i < LEDC_TEST_CH_NUM; i++) {
      ledc_set_duty(ledc_channel[i].speed_mode, ledc_channel[i].channel, 0);
      ledc_update_duty(ledc_channel[i].speed_mode, ledc_channel[i].channel);
      vTaskDelay(3000 / portTICK_PERIOD_MS);
    }
    gpio_set_level(LED_BLUETOOTH, 0);
    for (int i = 0; i < LEDC_TEST_CH_NUM; i++) {
      ledc_set_duty(ledc_channel[i].speed_mode, ledc_channel[i].channel, 1639);
      ledc_update_duty(ledc_channel[i].speed_mode, ledc_channel[i].channel);
      vTaskDelay(3000 / portTICK_PERIOD_MS);
    }

    for (int i = 0; i < LEDC_TEST_CH_NUM; i++) {
      ledc_set_duty(ledc_channel[i].speed_mode, ledc_channel[i].channel, 0);
      ledc_update_duty(ledc_channel[i].speed_mode, ledc_channel[i].channel);
      vTaskDelay(3000 / portTICK_PERIOD_MS);
    }

  }
}

void app_main(void) {

  ESP_LOGI(TAG, "power on-----");
  // 作为普通gpio
  gpio_config_t io_conf = {
      /*中断使能*/
      .intr_type = GPIO_INTR_DISABLE,
      /*输出模式调节*/
      .mode = GPIO_MODE_OUTPUT,
      /*配置引脚的掩码*/
      // .pin_bit_mask = (1ull << GPIO_NUM_12) | (1ull << LED_BLUETOOTH),
      .pin_bit_mask = (1ull << GPIO_NUM_12) | (1ull << LED1_GPIO),
      /*下拉使能*/
      .pull_down_en = 0,
      /*上拉使能*/
      .pull_up_en = 0,
  };
  gpio_config(&io_conf);
  // 开机
  gpio_set_level(GPIO_NUM_12, 1);
  
  // while(1){
  //   // led 蓝牙
  //   ESP_LOGI(TAG, "LED_BLUETOOTH 1");
  //   gpio_set_level(LED_BLUETOOTH, 1);
  //   vTaskDelay(3000 / portTICK_PERIOD_MS);
  //   ESP_LOGI(TAG, "LED_BLUETOOTH 0");
  //   gpio_set_level(LED_BLUETOOTH, 0);
  //   vTaskDelay(3000 / portTICK_PERIOD_MS);
  // }

  while(1){
      ESP_LOGI(TAG, "LED_test 1");
    gpio_set_level(LED1_GPIO, 1);
    vTaskDelay(3000 / portTICK_PERIOD_MS);
    ESP_LOGI(TAG, "LED_test 0");
    gpio_set_level(LED1_GPIO, 0);
    vTaskDelay(3000 / portTICK_PERIOD_MS);
  }

  // led_init();

  // xTaskCreate(led_start, "led_task", 2048 * 4, NULL, 3, NULL);
}


